<template>
  <div class="Three" ref="threeDom">
  </div>
</template>

<script setup lang="ts" name="Three">
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import * as THREE from 'three';
import { onMounted, ref } from 'vue';
const threeDom = ref();
const loader = new GLTFLoader();
onMounted(() => {
  let dom = threeDom.value
  console.log(threeDom.value);

  // 创建场景
  const scene = new THREE.Scene();
  /* 创建相机
    PerspectiveCamera：透视相机(远小近大)
    参数(视野角度,长宽比,近截面,远截面)
  */
  const camera = new THREE.PerspectiveCamera(75, dom.offsetWidth / dom.offsetHeight, 0.1, 1000);
  /* 接下来是渲染器
    renderer
  */
  const renderer = new THREE.WebGLRenderer();

  /* 除了创建一个渲染器，还得设置一个渲染器的尺寸
    参数(长度,宽度,分辨率)
    第三个参数可省略ture为以高分辨率渲染，false以低分辨率渲染
  */

  renderer.setSize(dom.offsetWidth, dom.offsetHeight);
  /* 将dom元素添加到页面中 */
  dom.appendChild(renderer.domElement);


  // 添加立方体

  /* BoxGeometry立方体对象 */
  const geometry = new THREE.BoxGeometry(1, 1, 1);

  /* MeshBasicMaterial材质
    提供了多种材质，这里以颜色{ color: 0x00ff00 }简单示例
  */
  const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });

  /* THREE.Mesh 
    我们需要一个网格，网格包含一个几何体，以及作用在几何体上面的材质
    此时直接操作网格对象即可
  */
  const cube = new THREE.Mesh(geometry, material);
  const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
  scene.add(directionalLight);
  loader.load('/threesrc/spiritBall.glb', function (gltf) {

    scene.add(gltf.scene);
    scene.add(cube)
    console.log(gltf);


  }, undefined, function (error) {

    console.error(error);

  })
  /* 场景添加 默认会添加到坐标(0,0,0)*/
  // scene.add(cube);

  /* 默认添加到(0,0,0)会使得摄像机和立方体对象处在同一个位置，我们只需要让摄像机移动一些即可 */
  camera.position.z = 5;


  /* 渲染场景 
    requestAnimationFrame？优势在于用户切换标签页时就会暂停动画，不占用额外的资源
    requestAnimationFrame()动画循环回调函数继续调用自身
  */

  function animate() {
    requestAnimationFrame(animate);
    /* 
      网格对象操作每次执行动画xy轴旋转0.01
    */
    cube.rotation.x += 0.01;
    cube.rotation.y += 0.01;

    renderer.render(scene, camera);
  }
  window.addEventListener('resize', () => {
    renderer.render(scene, camera);
  })
  animate();
})
</script>

<style lang="css" scoped>
.Three {
  width: 100%;
  height: 70vh;
  margin: 0 auto;
}
</style>
